/*
	Copyright (C) 2009 jungil Han <jungil.Han@gmail.com>

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "mkKeyboardDialog.h"

#include <QMessageBox>
#include <QKeyEvent>

mkKeyboardDialog::mkKeyboardDialog( IN QWidget *a_pParent, IN Qt::WindowFlags a_eFlags ) : mkDialog( a_pParent, a_eFlags )
{
	m_nPosX = -1;
	m_nPosY = -1;
	m_pNonSystemButtonGroup = NULL;
	m_pSystemButtonGroup = NULL;
}

mkKeyboardDialog::~mkKeyboardDialog()
{
	QList<QAbstractButton *> buttonList = m_pNonSystemButtonGroup->buttons();

	 while (!buttonList.isEmpty())
		delete buttonList.takeFirst();

	buttonList = m_pSystemButtonGroup->buttons();

	 while (!buttonList.isEmpty())
		delete buttonList.takeFirst();

	MK_DELETE( m_pNonSystemButtonGroup );
	MK_DELETE( m_pSystemButtonGroup );
}

void mkKeyboardDialog::OnInitDialog()
{
	/* Set the dialog's title */
	setWindowTitle( QString( "Keyboard" ));

	/* Set the dialog's size */
	resize( 253, 96 );
	setMaximumSize( 253, 96 );
	setMinimumSize( 253, 96 );

	/* Emit the keyboard event to Main dialog */
	connect( this, SIGNAL( SigUpdateKeyInfo( QString, QString )), parent(), SLOT( SlotHotkeyInfoUpdated( QString, QString )));

	/* Create the button group */
	if ( !m_pNonSystemButtonGroup )
		m_pNonSystemButtonGroup = new QButtonGroup( this );

	if ( !m_pSystemButtonGroup )
		m_pSystemButtonGroup = new QButtonGroup( this );

	/* Create the button */
	QRect fontRect( 1, 0, 19, 18 );
	for ( int nCnt = 0; nCnt < 12; nCnt++ ) {
		mkButton *pButton = new mkButton( this );
		pButton->SetBGImage( QString( ":/Keyboard/keyboard_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_btn_bg_click.png" ));
		pButton->setGeometry((( 20 + 1 ) * nCnt ) + 1, 1, 20, 18 );
		pButton->setCheckable( true );
		
		switch ( nCnt ) {
			case 0:	pButton->SetText( "F1", &fontRect, 5, Qt::AlignLeft );	break;
			case 1:	pButton->SetText( "F2", &fontRect, 5, Qt::AlignLeft );	break;
			case 2:	pButton->SetText( "F3", &fontRect, 5, Qt::AlignLeft );	break;
			case 3:	pButton->SetText( "F4", &fontRect, 5, Qt::AlignLeft );	break;
			case 4:	pButton->SetText( "F5", &fontRect, 5, Qt::AlignLeft );	break;
			case 5:	pButton->SetText( "F6", &fontRect, 5, Qt::AlignLeft );	break;
			case 6:	pButton->SetText( "F7", &fontRect, 5, Qt::AlignLeft );	break;
			case 7:	pButton->SetText( "F8", &fontRect, 5, Qt::AlignLeft );	break;
			case 8:	pButton->SetText( "F9", &fontRect, 5, Qt::AlignLeft );	break;
			case 9:	pButton->SetText( "F10", &fontRect, 5, Qt::AlignLeft );	break;
			case 10:	pButton->SetText( "F11", &fontRect, 5, Qt::AlignLeft );	break;
			case 11:	pButton->SetText( "F12", &fontRect, 5, Qt::AlignLeft );	break;
		}
		
		m_pNonSystemButtonGroup->addButton( pButton );
	}

	for ( int nCnt = 0; nCnt < 10; nCnt++ ) {
		mkButton *pButton = new mkButton( this );
		pButton->SetBGImage( QString( ":/Keyboard/keyboard_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_btn_bg_click.png" ));
		pButton->setGeometry((( 20 + 1 ) * nCnt ) + 1, 20, 20, 18 );
		pButton->setCheckable( true );

		switch ( nCnt ) {
			case 0:	pButton->SetText( "1", &fontRect, 6, Qt::AlignLeft );	break;
			case 1:	pButton->SetText( "2", &fontRect, 6, Qt::AlignLeft );	break;
			case 2:	pButton->SetText( "3", &fontRect, 6, Qt::AlignLeft );	break;
			case 3:	pButton->SetText( "4", &fontRect, 6, Qt::AlignLeft );	break;
			case 4:	pButton->SetText( "5", &fontRect, 6, Qt::AlignLeft );	break;
			case 5:	pButton->SetText( "6", &fontRect, 6, Qt::AlignLeft );	break;
			case 6:	pButton->SetText( "7", &fontRect, 6, Qt::AlignLeft );	break;
			case 7:	pButton->SetText( "8", &fontRect, 6, Qt::AlignLeft );	break;
			case 8:	pButton->SetText( "9", &fontRect, 6, Qt::AlignLeft );	break;
			case 9:	pButton->SetText( "0", &fontRect, 6, Qt::AlignLeft );	break;
		}
		
		m_pNonSystemButtonGroup->addButton( pButton );		
	}

	for ( int nCnt = 0; nCnt < 10; nCnt++ ) {
		mkButton *pButton = new mkButton( this );
		pButton->SetBGImage( QString( ":/Keyboard/keyboard_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_btn_bg_click.png" ));
		pButton->setGeometry((( 20 + 1 ) * nCnt ) + 1, 39, 20, 18 );
		pButton->setCheckable( true );

		switch ( nCnt ) {
			case 0:	pButton->SetText( "Q", &fontRect, 6, Qt::AlignLeft );	break;
			case 1:	pButton->SetText( "W", &fontRect, 6, Qt::AlignLeft );	break;
			case 2:	pButton->SetText( "E", &fontRect, 6, Qt::AlignLeft );	break;
			case 3:	pButton->SetText( "R", &fontRect, 6, Qt::AlignLeft );	break;
			case 4:	pButton->SetText( "T", &fontRect, 6, Qt::AlignLeft );	break;
			case 5:	pButton->SetText( "Y", &fontRect, 6, Qt::AlignLeft );	break;
			case 6:	pButton->SetText( "U", &fontRect, 6, Qt::AlignLeft );	break;
			case 7:	pButton->SetText( "I", &fontRect, 6, Qt::AlignLeft );	break;
			case 8:	pButton->SetText( "O", &fontRect, 6, Qt::AlignLeft );	break;
			case 9:	pButton->SetText( "P", &fontRect, 6, Qt::AlignLeft );	break;
		}
		
		m_pNonSystemButtonGroup->addButton( pButton );		
	}

	for ( int nCnt = 1; nCnt < 10; nCnt++ ) {
		mkButton *pButton = new mkButton( this );
		pButton->SetBGImage( QString( ":/Keyboard/keyboard_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_btn_bg_click.png" ));
		pButton->setGeometry((( 20 + 1 ) * nCnt ) + 1, 58, 20, 18 );
		pButton->setCheckable( true );

		switch ( nCnt ) {
			case 1:	pButton->SetText( "A", &fontRect, 6, Qt::AlignLeft );	break;
			case 2:	pButton->SetText( "S", &fontRect, 6, Qt::AlignLeft );	break;
			case 3:	pButton->SetText( "D", &fontRect, 6, Qt::AlignLeft );	break;
			case 4:	pButton->SetText( "F", &fontRect, 6, Qt::AlignLeft );	break;
			case 5:	pButton->SetText( "G", &fontRect, 6, Qt::AlignLeft );	break;
			case 6:	pButton->SetText( "H", &fontRect, 6, Qt::AlignLeft );	break;
			case 7:	pButton->SetText( "J", &fontRect, 6, Qt::AlignLeft );	break;
			case 8:	pButton->SetText( "K", &fontRect, 6, Qt::AlignLeft );	break;
			case 9:	pButton->SetText( "L", &fontRect, 6, Qt::AlignLeft );	break;
		}
		
		m_pNonSystemButtonGroup->addButton( pButton );
	}

	for ( int nCnt = 3; nCnt < 10; nCnt++ ) {
		mkButton *pButton = new mkButton( this );
		pButton->SetBGImage( QString( ":/Keyboard/keyboard_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_btn_bg_click.png" ));
		pButton->setGeometry((( 20 + 1 ) * nCnt ) + 1, 77, 20, 18 );
		pButton->setCheckable( true );

		switch ( nCnt ) {
			case 3:	pButton->SetText( "Z", &fontRect, 6, Qt::AlignLeft );	break;
			case 4:	pButton->SetText( "X", &fontRect, 6, Qt::AlignLeft );	break;
			case 5:	pButton->SetText( "C", &fontRect, 6, Qt::AlignLeft );	break;
			case 6:	pButton->SetText( "V", &fontRect, 6, Qt::AlignLeft );	break;
			case 7:	pButton->SetText( "B", &fontRect, 6, Qt::AlignLeft );	break;
			case 8:	pButton->SetText( "N", &fontRect, 6, Qt::AlignLeft );	break;
			case 9:	pButton->SetText( "M", &fontRect, 6, Qt::AlignLeft );	break;
		}
		
		m_pNonSystemButtonGroup->addButton( pButton );
	}

	fontRect = QRect( 1, 0, 40, 37 );
	mkButton *pOKButton = new mkButton( this );
	pOKButton->SetBGImage( QString( ":/Keyboard/keyboard_confirm_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_confirm_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_confirm_btn_bg_click.png" ));
	pOKButton->setGeometry((( 20 + 1 ) * 10 ) + 1, 20, 41, 37 );
	pOKButton->SetText( "OK", &fontRect, 6, Qt::AlignLeft );
	connect( pOKButton, SIGNAL( clicked() ), this, SLOT( SlotOKClicked() ));
	m_pNonSystemButtonGroup->addButton( pOKButton );

	mkButton *pCancelButton = new mkButton( this );
	pCancelButton->SetBGImage( QString( ":/Keyboard/keyboard_confirm_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_confirm_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_confirm_btn_bg_click.png" ));
	pCancelButton->setGeometry((( 20 + 1 ) * 10 ) + 1 , 58, 41, 37 );
	pCancelButton->SetText( "CANCEL", &fontRect, 6, Qt::AlignLeft );
	connect( pCancelButton, SIGNAL( clicked() ), this, SLOT( SlotCancelClicked() ));
	m_pNonSystemButtonGroup->addButton( pCancelButton );

	fontRect = QRect( 1, 1, 19, 17 );
	mkButton *pShiftButton = new mkButton( this );
	pShiftButton->SetBGImage( QString( ":/Keyboard/keyboard_system_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_click.png" ));
	pShiftButton->setGeometry( 1 , 58, 20, 18 );
	pShiftButton->SetText( "Shift", &fontRect, 5, Qt::AlignLeft );
	pShiftButton->setCheckable( true );
	m_pSystemButtonGroup->addButton( pShiftButton );

	mkButton *pCtrlButton = new mkButton( this );
	pCtrlButton->SetBGImage( QString( ":/Keyboard/keyboard_system_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_click.png" ));
	//pCtrlButton->setGeometry( 0, 76, 31, 18 );
	pCtrlButton->setGeometry( 1, 77, 20, 18 );
	pCtrlButton->SetText( "Ctrl", &fontRect, 5, Qt::AlignLeft );
	pCtrlButton->setCheckable( true );
	m_pSystemButtonGroup->addButton( pCtrlButton );

	mkButton *pWinButton = new mkButton( this );
	pWinButton->SetBGImage( QString( ":/Keyboard/keyboard_system_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_click.png" ));
	pWinButton->setGeometry( 22, 77, 20, 18 );
	pWinButton->SetText( "Win", &fontRect, 5, Qt::AlignLeft );
	pWinButton->setCheckable( true );
	m_pSystemButtonGroup->addButton( pWinButton );
	
	mkButton *pAltButton = new mkButton( this );
	pAltButton->SetBGImage( QString( ":/Keyboard/keyboard_system_btn_bg_default.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_over.png" ), QString( ":/Keyboard/keyboard_system_btn_bg_click.png" ));
	pAltButton->setGeometry( 43, 77, 20, 18 );
	//pAltButton->setGeometry( 32, 76, 30, 18 );
	pAltButton->SetText( "Alt", &fontRect, 5, Qt::AlignLeft );
	pAltButton->setCheckable( true );
	m_pSystemButtonGroup->addButton( pAltButton );
}

void mkKeyboardDialog::keyPressEvent( QKeyEvent *a_pEvent )
{
	switch ( a_pEvent->key() ) {
		case Qt::Key_Escape:
			close();
			a_pEvent->accept();
			break;
		default:
			a_pEvent->ignore();			
			break;
	}
}

void mkKeyboardDialog::showEvent( QShowEvent *a_pEvent )
{
	if ( m_nPosX == -1 && m_nPosY == -1) {
		QPoint point( pos().x(), pos().y() );
		point.ry() += 111;
		move( point );
	} else 
		move( m_nPosX, m_nPosY );
}

void mkKeyboardDialog::closeEvent( QCloseEvent *a_pEvent )
{
	SavePosition();
}

void mkKeyboardDialog::SavePosition()
{
	m_nPosX = pos().x();
	m_nPosY = pos().y();
	//parentWidget()->setWindowTitle( QString(" %1 x %2").arg( m_nPosX ).arg( m_nPosY ));	
}

void mkKeyboardDialog::SetToggle( IN QString a_strText )
{
	QList<QAbstractButton *> buttonList = m_pNonSystemButtonGroup->buttons();
	
	for ( int nIndex = 0; nIndex < buttonList.size(); ++nIndex ) {
		if ( reinterpret_cast<mkButton *>( buttonList.at( nIndex ))->GetText() == a_strText ) {
			buttonList.at( nIndex )->setChecked( true );
			return ;
		}
	}

	buttonList = m_pSystemButtonGroup->buttons();

	for ( int nIndex = 0; nIndex < buttonList.size(); ++nIndex ) {
		if ( reinterpret_cast<mkButton *>( buttonList.at( nIndex ))->GetText() == a_strText ) {
			buttonList.at( nIndex )->setChecked( true );
			return ;
	    }
	}

	/* 등록된 Hotkey가 없을 경우, 클릭된 키가 없도록 초기화 */
	QAbstractButton *pButton =  m_pSystemButtonGroup->checkedButton();
	if ( pButton ) {
		m_pSystemButtonGroup->setExclusive( false );
		pButton->setChecked( false );			
		m_pSystemButtonGroup->setExclusive( true );
	}
	
	pButton =  m_pNonSystemButtonGroup->checkedButton();
	if ( pButton ) {
		m_pNonSystemButtonGroup->setExclusive( false );
		pButton->setChecked( false );			
		m_pNonSystemButtonGroup->setExclusive( true );		
	}
}

void mkKeyboardDialog::SlotOKClicked()
{
	QString strSystemText, strNonSystemText;

	mkButton *pSystemButton = reinterpret_cast<mkButton *>( m_pSystemButtonGroup->checkedButton() );	
	if ( pSystemButton )
		strSystemText = pSystemButton->GetText();
	
	mkButton *pNonSystemButton = reinterpret_cast<mkButton *>( m_pNonSystemButtonGroup->checkedButton() );
	if ( pNonSystemButton )
		strNonSystemText = pNonSystemButton->GetText();

	if ( !strSystemText.isEmpty() && !strNonSystemText.isEmpty() )
		emit SigUpdateKeyInfo( strSystemText, strNonSystemText );

	SavePosition();
	accept();
	
}

void mkKeyboardDialog::SlotCancelClicked()
{
	SavePosition();		
	reject();
}
